from flask import Flask, request, jsonify
from flask_cors import CORS
import os
import shutil
import schedule
import time
from threading import Thread
from processor import Processor
from cell_segmentation import CellSegmentation
from cell_feature_extraction import CellFeatureExtraction
from red_blood_cell_differential import RedBloodCellDifferential
from image_feature_extraction import ImageFeatureExtraction
from classification_diseases import ClassificationDiseases
from cell_image_processor import CellImageProcessor

app = Flask(__name__)
CORS(app)

# @name predict 预测接口
# @param {string} recordId 记录ID
# @param {string} patientId 病人ID
# @param {array} bloodRoutineIndicators 血常规指标数据
# @return {object} 预测结果
@app.route('/predict', methods=['POST'])
def predict():
    data = request.get_json()
    recordId = data['recordId']
    patientId = data['patientId']
    bloodRoutineIndicators = data['bloodRoutineIndicators']
    # 创建 DataProcessor 实例
    data_processor = Processor(
    model_path='models/best_svm_model.joblib',
    scaler_path='models/scaler.joblib',
    imputer_path='models/imputer.joblib'
    )
    # 使用 DataProcessor 进行预测并保存结果
    return data_processor.predict_and_save(patientId, recordId, bloodRoutineIndicators)

# @name saveNewrecord 保存为newRecord接口
# @param {string} recordID记录ID
# @param {string} patientId病人ID
# @return {object} newRecord新的记录ID
@app.route('/saveRecord', methods=['PUT'])
def saveRecord():
    data = request.get_json()
    recordId = data['recordId']
    patientId = data['patientId']
    newRecordId = data['newRecordId']

    # 原始路径：temp/患者ID
    temp_patient_dir = os.path.join("temp", patientId)
    
    # 检查患者目录是否存在
    if not os.path.exists(temp_patient_dir):
        return jsonify({"success": False, "message": "患者目录不存在"}), 400

    # 查找所有匹配的目录（以recordId开头，可能带括号数字的）
    matched_dirs = [d for d in os.listdir(temp_patient_dir) if d.startswith(recordId) and os.path.isdir(os.path.join(temp_patient_dir, d))]
    
    if not matched_dirs:
        return jsonify({"success": False, "message": "未找到匹配的记录目录"}), 400

    # 目标路径：patient/患者ID
    patient_target_dir = os.path.join("patient", patientId)
    os.makedirs(patient_target_dir, exist_ok=True)

    try:
        # 遍历所有匹配的目录
        for i, original_dir_name in enumerate(matched_dirs):
            original_dir = os.path.join(temp_patient_dir, original_dir_name)
            
            new_dir = os.path.join(patient_target_dir, newRecordId,f"({i+1})" )
            
            # 重命名并移动目录
            shutil.move(original_dir, new_dir)
            # 检查是否存在对应的.csv文件
            csv_file_name = f"{recordId}.csv"
            csv_file_path = os.path.join(temp_patient_dir, csv_file_name)
            
            if os.path.exists(csv_file_path):
                # 移动.csv文件到新目录并重命名
                new_csv_path = os.path.join(patient_target_dir, newRecordId,f"{newRecordId}.csv")
                shutil.move(csv_file_path, new_csv_path)
        
    except Exception as e:
        return jsonify({"success": False, "message": str(e)}), 500

    return jsonify({"success": True}), 200

# @name imageDetection 图像检测接口
# @param {string} recordId 记录ID
# @param {string} patientId 病人ID
# @param {string} image 图像数据
# @return {object} 预测结果
@app.route('/imageDetection', methods=['POST'])
def imageDetection():
    data = request.get_json()
    print(data)
    recordId = data['recordId']
    patientId = data['patientId']
    image = data['img']
    # 创建 CellSegmentation 实例并处理图像
    print('创建 CellSegmentation 实例并处理图像开始')
    cell_segmentation = CellSegmentation(patientId,recordId)
    imagePath = cell_segmentation.process_image(image)
    print('创建 CellSegmentation 实例并处理图像成功')
    if imagePath is None:
        return jsonify({"error": "图像处理失败"}), 500
    # 在创建特征提取输出目录时记录路径
    print('在创建特征提取输出目录时记录路径开始')
    temp_folder = os.path.join("temp", patientId)
    folder_monitor[temp_folder] = time.time()  # 新增监控
    print('在创建特征提取输出目录时记录路径成功')
    # 创建 CellFeatureExtraction 实例并提取特征
    print('创建 CellSegmentation 实例并处理图像开始')
    output_file = os.path.join("temp", patientId, recordId, "cell_feature_extraction.csv")
    cell_feature_extraction = CellFeatureExtraction(imagePath, output_file)
    feature_results_path = cell_feature_extraction.run()
    print('创建 CellSegmentation 实例并处理图像成功')
    if feature_results_path is None:
        return jsonify({"error": "特征提取失败"}), 500
    #调用红细胞分类模型进行预测
    print('调用红细胞分类模型进行预测开始')
    red_blood_cell_differential = RedBloodCellDifferential('models/trained_model.joblib')
    result = red_blood_cell_differential.predict(feature_results_path)
    print('调用红细胞分类模型进行预测成功')
    if result is None:
        return jsonify({"error": "红细胞分类失败"}), 500
    #生成图像
    print('生成图像开始')
    cell_image_processor = CellImageProcessor(result)
    imgUrl = cell_image_processor.process_image(patientId,recordId,image)
    print('生成图像成功')
    if imgUrl is None:
        return jsonify({"error": "图像生成失败"}), 500
    #图像特征提取
    print('图像特征提取开始')
    image_feature_extraction = ImageFeatureExtraction(result)
    summary = image_feature_extraction.analyze_csv()
    print('图像特征提取成功')
    if summary is None:
        return jsonify({"error": "图像特征提取失败"}), 500
    #疾病分类
    print('疾病分类开始')
    classification_diseases = ClassificationDiseases('models/trained_adaboost_model.joblib')
    imgProbability = classification_diseases.predict(summary)
    print('疾病分类成功')
    if imgProbability is None:
        return jsonify({"error": "疾病分类失败"}), 500
    #返回结果
    total = imgUrl['total']
    recordId = imgUrl['recordId']
    details = imgUrl['details']
    
    # 创建最终结果字典
    final_result = {
        'recordId': recordId,
        'total': total,
        'originalImageUrl': image,
        'imgProbability': imgProbability,
        'details': details
    }
    print(final_result)
    # 返回结果
    return jsonify(final_result)

folder_monitor = {}  # 用于跟踪文件夹创建时间
def check_expired_folders():
    print("正在检查过期文件夹...")
    current_time = time.time()
    expired_folders = []
    
    # 遍历监控字典
    for folder_path, create_time in list(folder_monitor.items()):
        if current_time - create_time > 1800:  # 30分钟=1800秒
            if os.path.exists(folder_path):
                try:
                    shutil.rmtree(folder_path)
                    print(f"已删除过期文件夹: {folder_path}")
                except Exception as e:
                    print(f"删除文件夹失败: {folder_path} - {str(e)}")
            expired_folders.append(folder_path)
    
    # 清理已处理记录
    for folder in expired_folders:
        del folder_monitor[folder]


# 每分钟检查一次过期文件夹
schedule.every(1).minutes.do(check_expired_folders)

def run_schedule():
    while True:
        schedule.run_pending()
        time.sleep(1)

if __name__ == '__main__':
    # 启动 schedule 任务线程
    schedule_thread = Thread(target=run_schedule)
    schedule_thread.start()
    # 启动 Flask 应用
    app.run(host='0.0.0.0', port=5000)